﻿using System;
using FindDihotTDD;


namespace Presentation
{
    public class Presenter
    {
        private SearchDichotomy sdich;
        private IView view;
        private ILogger LOG;

        public Presenter(IView view, ILogger log)
        {
            this.view = view;
            this.LOG = log;
            sdich = new SearchDichotomy();
            Setup();
        }

        private void Setup()
        {
            view.OnFindClick += FindElement;
            view.OnOpenLogClick += OpenLog;
        }

         void OpenLog()
        {
            view.logging = System.IO.File.ReadAllText(LOG.getLogFileName());
        }

        public void FindElement()
        {
            view.error = "";
            int x;
            int resultPos;
            string stringMas = view.mas;
            try
            {
                if (stringMas.Length == 0)
                {
                    throw new Exception("Error: The array is empty.");
                }
                else
                {
                    int[] array = ParseMas(stringMas);
                    x = CheckFormatOfElement();

                    resultPos = sdich.dichotSearch(array, x);
                    outputResults(resultPos, array);
                }
            }
            catch (Exception e)
            {
                view.error = e.Message;
                view.pos = "Element is not Exist.";
            }
            finally
            {
                logging(LOG);
            }
            
        }

        private void outputResults(int position, int[] mas)
        {
            if (position != -1)
            {
                view.pos = position.ToString();
            }
            else
            {
                view.pos = "Element is not Exist.";
                view.error = "Info: Element not found!";
            }
            view.sortedMas = convertMasToString(mas);
        }


        public int[] ParseMas(string stringMas)
        {
            if (stringMas.Equals(""))
            {
                throw new Exception("Mas is Empty");
            }
            string[] split = view.mas.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            int[] array = new int[split.Length];
            for (int i = 0; i < split.Length; i++)
            {
                try
                {
                    array[i] = Int32.Parse(split[i].Trim());
                }
                catch (FormatException)
                {
                    LOG.Write("Mas parse is fail");
                    throw new Exception("Error: Incorrect data.");  
                }
                LOG.Write("Mas is parsed successfully");
            }
            return array;
        }

        private string convertMasToString(int[] mas)
        {
            string result = "[";
            for (int i = 0; i < mas.Length; i++)
            {
                result = result + Convert.ToString(mas[i]) + ", ";
            }
            result += "]";
                return result;
        }

        public void logging(ILogger log)
        {
            string text = "Data-in:" + "\n";
            log.Write(text);
            text = "Input Array: " + view.mas + "\n";
            log.Write(text);
            text = "Required Element: " + view.requiredElement + "\n";
            log.Write(text);
            text = "Data-out:" + "\n";
            log.Write(text);
            if (view.error == "")
            {
                text = "Sorted array: " + view.sortedMas + "\n";
                log.Write(text);
                text = "Position of element: " + view.pos + "\n";
                log.Write(text);
            }
            else
            {
                text += "Error message: " + view.error + "\n";
            }
            log.Write(text);
        }

        public void SetView(IView view)
        {
            this.view = view;
            Setup();
        }
        public int CheckFormatOfElement()
        {
          if (view.requiredElement.Equals(""))
            {
                throw new Exception("Element is Empty!");
            }
            int elementToFind;
            try
            {
                elementToFind = Int32.Parse(view.requiredElement.Trim());
            }
            catch (FormatException)
            {
                LOG.Write("Error:CheckFormatOfElement is failed");
                throw new Exception("Incorrect Format!");
            }
            LOG.Write("CheckFormatOfElement performed successfully");
            return elementToFind;
        }
    }
}
